/*
 * @Author: ipk518 121206530@qq.com
 * @Date: 2023-11-20 09:04:02
 * @LastEditors: ipk518 121206530@qq.com
 * @LastEditTime: 2024-03-07 19:45:20
 * @FilePath: /moduleTest/src/gpio.c
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include <unistd.h>
#include <fcntl.h>
#include "gpio.h"
#include "myLog.h"
#include "string.h"
/**
 * @description: 初始化GPIO口，设置gpio方向set gpio "in" or "out" 
 * @param {int} gpion
 * @param {char} *direction
 * @param {int} len
 * @return {*}
 */
void gpioExport(int gpion,const char *direction,int len)  
{  
    int  exportfd, directionfd;
    char path[64];
    if(gpion <= 0){
        qlog_e("gpio num is null:%d",gpion);
        return;
    }
    // The GPIO has to be exported to be able to see it
    // in sysfs
    exportfd = open("/sys/class/gpio/export", O_WRONLY);
    if (exportfd < 0)
    {
        qlog_e("Cannot open GPIO to export it");
        return;
    }
    snprintf(path, sizeof(path), "%d", gpion);
    write(exportfd, path, sizeof(path));
    close(exportfd);
    qlog_i("GPIO exported successfully");
    // Update the direction of the GPIO to be an output
    memset(path,0,sizeof(path));
    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", gpion); 
    directionfd = open(path, O_RDWR);
    if (directionfd < 0)
    {
        qlog_e("Cannot open GPIO direction it");
        return;
    }
    if(len > 3){
        write(directionfd, "out", len);
    }else{
        write(directionfd, "in", len);
    }
    // write(directionfd, direction, len);
    close(directionfd);
    qlog_i("GPIO direction set as output successfully:%d",gpion);
}   //create gpio file

/**
 * @description: 关闭GPIO口
 * @param {unsigned int} gpio
 * @return {*}
 */
int gpioUnexport(unsigned int gpion)
{
    int fd, len;
    char buf[64];
    fd = open("/sys/class/gpio/unexport", O_WRONLY);//打开文件
    if (fd < 0) {
        perror("gpio/export");
        return fd;
    }
 
    len = snprintf(buf, sizeof(buf), "%d", gpion);//从数字变换为字符串，即1 变为”1“
    write(fd, buf, len);//将需要取消导出的GPIO引脚编号进行写入
    close(fd);//关闭文件
    return 0;
 }

/**
 * @description: 设置gpio的电平
 * @param {int} n
 * @param {int} value
 * @return {*}
 */
void setGpioValue(int n, int value)
{
	char path[64];
    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", n);
    int tmp,res;
    tmp = open(path, O_WRONLY);
	if (tmp < 0)
    {
        qlog_e("direction open filed:gpio %d",n);
        return;
    }
    if(value > 0)
        res = write(tmp, "1", 2);
    else
        res = write(tmp, "0", 2);

    if(res < 0){
                qlog_e("write open filed:gpio %d",n);
    }
    close(tmp);
} 

/**
 * @description: 获取gpio的值
 * @param {int} n
 * @return {*}
 */ 
int getGpioValue(int n)  
{  
    char path[64];
    char value_str[3];
    int fd,res;

    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", n);  
    fd = open(path, O_RDONLY);  
    if (fd < 0) {
        qlog_e("Failed to open gpio value for reading!");  
        return -1;
    }


    if (read(fd, value_str, 1) < 0) {  
        qlog_e("Failed to read value!");  
        close(fd);
        return -1;
    }

    if (value_str[0] != '0') {
		res = 1;
	} else {
		res = 0;
	}

    close(fd);
    return res; 
}   //get gpio(n)'s value  

/**
 * @description: 设置上升下降沿触发
 * @param {int} n
 * @return {*}
 */
void setGpioEdge(int n)
{
    char path[64],cmd[64];
    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/edge", n);
    snprintf(cmd, 64, "echo rising  > %s", path);
    if (system(cmd) != 0) {
        fprintf(stderr, "Error: Failed to turn off %s\n", path);
    }
}


/* User-operable LEDs */
static char *g_leds[] = {
    "/sys/class/leds/user-led0",
    "/sys/class/leds/user-led1",
};

void controlLed()
{
    int i = 0;
    int c = 0;
    int num = 2;
    char cmd[64] = {0};
    qlog_i("Flashing leds :");
    for (i = 0; i < num; i++)
        qlog_i("%s",g_leds[i]);


    /* Turn on LEDs */
    for (i = 0; i < num; i++) {
        /* Set the LED brightness value to 1 to turn on the led */
        snprintf(cmd, 64, "echo 1 > %s/brightness", g_leds[i]);
        if (system(cmd) != 0) {
            fprintf(stderr, "Error: Failed to turn on %s\n", g_leds[i]);
            exit(EXIT_FAILURE);
        }
    }
    /* Keep the LEDs on for 500 ms */
    usleep(500 * 1000);

    /* Turn off LEDs */
    for (i = 0; i < num; i++) {
        /* Set the LED brightness value to 0 to turn off the LED */
        snprintf(cmd, 64, "echo 0 > %s/brightness", g_leds[i]);
        if (system(cmd) != 0) {
            fprintf(stderr, "Error: Failed to turn off %s\n", g_leds[i]);
            exit(EXIT_FAILURE);
        }
    }

    /* Keep the LEDs off for 500 ms */
    usleep(500 * 1000);
}